home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / ae_14.zip / AE1.PAS < prev    next >
Pascal/Delphi Source File  |  1991-03-08  |  22KB  |  611 lines

  1. unit AE1 ;
  2.  
  3. {$B-}
  4. {$I-}
  5. {$S+}
  6. {$V-}
  7.  
  8. {-----------------------------------------------------------------------------}
  9. { This unit contains all basic procedures                                     }
  10. {-----------------------------------------------------------------------------}
  11.  
  12. interface
  13.  
  14. uses Crt,Dos,AE0 ;
  15.  
  16. function UpperCase (S:string) : string ;
  17. function WordToString (Num:word ; Len:integer) : string ;
  18. function Wildcarded (Name : PathStr) : boolean ;
  19. function Exists (FileName : PathStr) : boolean ;
  20. procedure MoveToScreen (var Source,Dest ; Len : word) ;
  21. procedure MoveFromScreen (var Source,Dest ; Len : word) ;
  22. procedure SaveArea (X1,Y1,X2,Y2:word ; var MemPtr:ScreenBlockPtr) ;
  23. procedure RestoreArea (X1,Y1,X2,Y2:word ; var MemPtr:ScreenBlockPtr) ;
  24. function Grow (Index:word ; Chars:word) : boolean ;
  25. procedure Shrink (Index:word ; Chars:word) ;
  26. function GetCursor : byte ;
  27. procedure SetCursor (Cursor : byte) ;
  28. procedure CursorTo (X,Y : byte) ;
  29. procedure WarningBeep ;
  30. function ReadKeyNr : word ;
  31. procedure SetBottomLine (LineText:string) ;
  32. procedure Message (Contents:string) ;
  33. procedure ErrorMessage (ErrorNr:byte) ;
  34. procedure Pause ;
  35. procedure CheckDiskError ;
  36. procedure PutFrame (X1,Y1,X2,Y2 : byte ; Border : string) ;
  37. procedure ClearArea (X1,Y1,X2,Y2 : byte) ;
  38. procedure ClearWorkspace (Wsnr:byte) ;
  39. procedure ClearKeyBuffer ;
  40.  
  41. implementation
  42.  
  43. {-----------------------------------------------------------------------------}
  44. { Converts all lower case letters in a string to upper case.                  }
  45. {-----------------------------------------------------------------------------}
  46.  
  47. function UpperCase (S : string) : string ;
  48.  
  49. var Counter : word ;
  50.  
  51. begin
  52. for Counter := 1 to Length(S) do S[Counter] := UpCase (S[Counter]) ;
  53. UpperCase := S ;
  54. end ;
  55.  
  56. {-----------------------------------------------------------------------------}
  57. { Converts an expression of type word to a string                             }
  58. { if Len < 0 then string is adjusted to the left; string length is <Len>      }
  59. { if Len > 0 then string is adjusted to the right; string length is <-Len>    }
  60. { if Len = 0 then string is not adjusted; string has minimum length           }
  61. {-----------------------------------------------------------------------------}
  62.  
  63. function WordToString (Num:word ; Len:integer) : string ;
  64.  
  65. var S : string[5] ;
  66.  
  67. begin
  68. if Len > 0
  69.    then Str (Num:Len,S)
  70.    else begin
  71.         Str (Num,S) ;
  72.         Len := - Len ;
  73.         if (Len > 0) and (Length(S) < Len)
  74.            then begin
  75.                 FillChar (S[Length(S)+1],Len-Length(S),' ') ;
  76.                 S[0] := Chr(Len) ;
  77.                 end ;
  78.         end ;
  79. WordToString := S ;
  80. end ;
  81.  
  82. {-----------------------------------------------------------------------------}
  83. { Deletes all spaces on the left of a string.                                 }
  84. {-----------------------------------------------------------------------------}
  85.  
  86. function TrimLeft (S:string) : string ;
  87.  
  88. begin
  89. while (Length(S) >0) and (S[1] = ' ') do Delete (S,1,1) ;
  90. TrimLeft := S ;
  91. end ;
  92.  
  93. {-----------------------------------------------------------------------------}
  94. { Indicates whether a filename contains wildcard characters                   }
  95. {-----------------------------------------------------------------------------}
  96.  
  97. function Wildcarded (Name : PathStr) : boolean ;
  98.  
  99. begin
  100. Wildcarded := (Pos('*',Name) <> 0) or (Pos('?',Name) <> 0) ;
  101. end ;
  102.  
  103. {-----------------------------------------------------------------------------}
  104. { Returns True if the file <FileName> exists, False otherwise.                }
  105. {-----------------------------------------------------------------------------}
  106.  
  107. function Exists (FileName : PathStr) : boolean ;
  108.  
  109. var SR : SearchRec ;
  110.  
  111. begin
  112. FindFirst (FileName,ReadOnly + Hidden + SysFile,SR) ;
  113. Exists := (DosError = 0) and (not Wildcarded(Filename)) ;
  114. end ;
  115.  
  116. {-----------------------------------------------------------------------------}
  117. { Moves <Len> bytes of memory to screen memory.                               }
  118. { From the TCALC spreadsheet program delivered with every copy of Turbo       }
  119. { Pascal 5.5                                                                  }
  120. {-----------------------------------------------------------------------------}
  121.  
  122. procedure MoveToScreen (var Source,Dest ; Len : word) ;
  123.  
  124. external ;
  125.  
  126. {-----------------------------------------------------------------------------}
  127. { Moves <Len> bytes of screen memory to memory.                               }
  128. { From the TCALC spreadsheet program delivered with every copy of Turbo       }
  129. { Pascal 5.5                                                                  }
  130. {-----------------------------------------------------------------------------}
  131.  
  132. procedure MoveFromScreen (var Source,Dest ; Len : word) ;
  133.  
  134. external ;
  135.  
  136. {$L TCMVSMEM.OBJ }
  137.  
  138. {-----------------------------------------------------------------------------}
  139. { Saves the contents of a rectangular part of the screen to memory.           }
  140. { Upper left corner is (X1,Y1), lower right is (X2,Y2)                        }
  141. { Also claims the amount of memory needed.                                    }
  142. {-----------------------------------------------------------------------------}
  143.  
  144. procedure SaveArea (X1,Y1,X2,Y2:word ; var MemPtr:ScreenBlockPtr) ;
  145.  
  146. var LineLen : byte;
  147.     Index : word;
  148.     Counter : byte;
  149.  
  150. begin
  151. LineLen := X2 - X1 + 1;
  152. GetMem (MemPtr,LineLen*(Y2-Y1+1)*2) ;
  153. Index := 1 ;
  154. for Counter := Y1 to Y2 do
  155.     begin
  156.     MoveFromScreen (DisplayPtr^[Counter,X1],MemPtr^[Index],LineLen*2);
  157.     Inc (Index,LineLen)
  158.     end;
  159. {$IFDEF DEVELOP }
  160. if MemAvail < MinMemAvail
  161.    then MinMemAvail := MemAvail ;
  162. {$ENDIF }
  163. end;
  164.  
  165. {-----------------------------------------------------------------------------}
  166. { Reverse of SaveArea                                                         }
  167. {-----------------------------------------------------------------------------}
  168.  
  169. procedure RestoreArea (X1,Y1,X2,Y2:word ; var MemPtr:ScreenBlockPtr) ;
  170.  
  171. var LineLen : byte;
  172.     Index : word;
  173.     Counter : byte;
  174.  
  175. begin
  176. LineLen := X2 - X1 + 1;
  177. Index := 1;
  178. for Counter := Y1 to Y2 do
  179.     begin
  180.     MoveToScreen (MemPtr^[Index],DisplayPtr^[Counter,X1],LineLen*2);
  181.     Inc (Index,LineLen)
  182.     end;
  183. FreeMem (MemPtr,LineLen*(Y2-Y1+1)*2) ;
  184. end;
  185.  
  186. {-----------------------------------------------------------------------------}
  187. { Expands the text in the buffer of the current workspace at position         }
  188. { <Index> by <Chars> characters. Function result is False if there is not     }
  189. { enough space left, True otherwise.                                          }
  190. { Index values of Mark and in position stack are adapted                      }
  191. {-----------------------------------------------------------------------------}
  192.  
  193. function Grow (Index:word ; Chars:word) : boolean ;
  194.  
  195. var Counter : byte ;
  196.  
  197. begin
  198. with Workspace[CurrentWsnr] do
  199.      if Chars > (WsBufSize - BufferSize)
  200.         then begin
  201.              { not enough space }
  202.              ErrorMessage (1) ;
  203.              Grow := False ;
  204.              end
  205.         else begin
  206.              { move rest of text forward }
  207.              Move (Buffer^[Index],Buffer^[Index+Chars],BufferSize-Index+1) ;
  208.              Inc (BufferSize,Chars) ;
  209.              { adapt Mark and position stack }
  210.              if Mark >= Index then Inc (Mark,Chars) ;
  211.              for Counter := 1 to PosStackpointer do
  212.                  begin
  213.                  if PosStack[Counter] >= Index
  214.                     then Inc (PosStack[Counter],Chars) ;
  215.                  end ;
  216.              ChangesMade := True ;
  217.              Grow := True ;
  218.              end ;
  219. end ;
  220.  
  221. {-----------------------------------------------------------------------------}
  222. { Deletes <Chars> characters from the buffer in the current workspace,        }
  223. { starting on position <Index>.                                               }
  224. { Index values of Mark and in position stack are adapted                      }
  225. {-----------------------------------------------------------------------------}
  226.  
  227. procedure Shrink (Index:word ; Chars:word) ;
  228.  
  229. var Counter : word ;
  230.  
  231. begin
  232. with Workspace[CurrentWsnr] do
  233.      begin
  234.      { move rest of text backward }
  235.      Move (Buffer^[Index+Chars],Buffer^[Index],BufferSize-(Index+Chars)+1) ;
  236.      Dec (BufferSize,Chars) ;
  237.      { adapt Mark }
  238.      if (Mark >= Index)
  239.         then begin
  240.              if (Mark < (Index+Chars))
  241.                 then Mark := Inactive
  242.                 else Dec (Mark,Chars) ;
  243.              end ;
  244.      { adapt position stack }
  245.      for Counter := 1 to PosStackpointer do
  246.          if (PosStack[Counter] >= Index)
  247.             then begin
  248.                  if (PosStack[Counter] < (Index+Chars))
  249.                     then PosStack[Counter] := Index
  250.                     else Dec (PosStack[Counter],Chars) ;
  251.                  end ;
  252.      ChangesMade := True ;
  253.      end ;
  254. end ;
  255.  
  256. {-----------------------------------------------------------------------------}
  257. { Returns the current cursor type                                             }
  258. {-----------------------------------------------------------------------------}
  259.  
  260. function GetCursor : byte ;
  261.  
  262. var Reg : registers ;
  263.  
  264. begin
  265. with Reg do
  266.      begin
  267.      AH := 3 ;
  268.      BH := 0 ;
  269.      { call BIOS interrupt }
  270.      Intr ($10,Reg) ;
  271.      case CX of
  272.           $0607,$0B0C : GetCursor := UnderLineCursor ;
  273.           $0507,$090C : GetCursor := HalfBlockCursor ;
  274.           $0807,$0D0C : GetCursor := BlockCursor ;
  275.           $2000       : GetCursor := Inactive ;
  276.           $2001       : GetCursor := NoBlinkCursor ;
  277.           else          GetCursor := UnderLineCursor ;
  278.           end ; { of case }
  279.      end ; { of with }
  280. end ;
  281.  
  282. {-----------------------------------------------------------------------------}
  283. { Sets a new cursor                                                           }
  284. {-----------------------------------------------------------------------------}
  285.  
  286. procedure SetCursor (Cursor : byte) ;
  287.  
  288. var Reg : registers ;
  289.     ScrEl : ScreenElement ;
  290.  
  291. begin
  292. if Config.Setup.CursorType = NoBlinkCursor
  293.    then begin
  294.         { remove NoBlinkCursor from old position: reset attribute }
  295.         ScrEl := ScreenElement (DisplayPtr^[WhereY,WhereX]) ;
  296.         ScrEl.attribute := OldCursorPosAttr ;
  297.         DisplayPtr^[WhereY,WhereX] := word (ScrEl) ;
  298.         end ;
  299. with Reg do
  300.      begin
  301.      AH := 1 ;
  302.      BH := 0 ;
  303.      { monochrome and color cards require different settings for cursor shape }
  304.      case Cursor of
  305.           Inactive        : CX := $2000 ;
  306.           UnderLineCursor : if Colorcard then CX := $0607 else CX := $0B0C ;
  307.           HalfBlockCursor : if Colorcard then CX := $0507 else CX := $090C;
  308.           BlockCursor     : if Colorcard then CX := $0807 else CX := $0D0C ;
  309.           NoBlinkCursor   : CX := $2001 ;
  310.           end ; { of case }
  311.      { call BIOS interrupt }
  312.      Intr ($10,Reg) ;
  313.      end ; { with }
  314. if Cursor = NoBlinkCursor
  315.    then begin
  316.         { put NoBlinkCursor on new position }
  317.         ScrEl := ScreenElement (DisplayPtr^[WhereY,WhereX]) ;
  318.         { save original attribute }
  319.         OldCursorPosAttr := ScrEl.attribute ;
  320.         { set cursor attribute }
  321.         with ScreenColorArray[Config.Setup.ScreenColors] do
  322.              ScrEl.Attribute := CursorAttr ;
  323.         DisplayPtr^[WhereY,WhereX] := word (ScrEl) ;
  324.         end ;
  325. end ;
  326.  
  327. {-----------------------------------------------------------------------------}
  328. { Positions the cursor at (X,Y)                                               }
  329. {-----------------------------------------------------------------------------}
  330.  
  331. procedure CursorTo (X,Y : byte) ;
  332.  
  333. var ScrEl : ScreenElement ;
  334.  
  335. begin
  336. if Config.Setup.CursorType = NoBlinkCursor
  337.    then begin
  338.         { remove NoBlinkCursor from old position: reset attribute }
  339.         ScrEl := ScreenElement (DisplayPtr^[WhereY,WhereX]) ;
  340.         ScrEl.attribute := OldCursorPosAttr ;
  341.         DisplayPtr^[WhereY,WhereX] := word (ScrEl) ;
  342.         end ;
  343. GotoXY (X,Y) ;
  344. if Config.Setup.CursorType = NoBlinkCursor
  345.    then begin
  346.         { put NoBlinkCursor on new position }
  347.         ScrEl := ScreenElement (DisplayPtr^[Y,X]) ;
  348.         { save original attribute }
  349.         OldCursorPosAttr := ScrEl.attribute ;
  350.         { set cursor attribute }
  351.         with ScreenColorArray[Config.Setup.ScreenColors] do
  352.              ScrEl.Attribute := CursorAttr ;
  353.         DisplayPtr^[Y,X] := word (ScrEl) ;
  354.         end ;
  355. end ;
  356.  
  357. {-----------------------------------------------------------------------------}
  358. { Produces a low beep trough the speaker, unless inhibited by Setup           }
  359. {-----------------------------------------------------------------------------}
  360.  
  361. procedure WarningBeep ;
  362.  
  363. begin
  364. if Config.Setup.SoundBell
  365.    then begin
  366.         Sound (110) ;
  367.         Delay (100) ;
  368.         NoSound ;
  369.         end ;
  370. end ;
  371.  
  372. {-----------------------------------------------------------------------------}
  373. { Waits until a key on the keyboard is pressed and returns its key number.    }
  374. { Control keys (cursor keys, function keys etc.) are translated to numbers    }
  375. { above 255.                                                                  }
  376. {-----------------------------------------------------------------------------}
  377.  
  378. function ReadKeyNr : word ;
  379.  
  380. var Regs : registers ;
  381.  
  382. begin
  383. with Regs do
  384.      begin
  385.      AH := 0 ;
  386.      Intr ($16,Regs) ;
  387.      { AL now contains the ASCII value of the key, AH the scan code }
  388.      case AL of
  389.            0 : if AH = 3  then ReadKeyNr := 0    { ^@ }
  390.                           else ReadKeyNr := 256 + AH ;
  391.            8 : if AH = 14 then ReadKeyNr := BkspKey
  392.                           else ReadKeyNr := 8 ;  { ^H }
  393.            9 : if AH = 15 then ReadKeyNr := TabKey
  394.                           else ReadKeyNr := 9 ;  { ^I }
  395.           10 : if AH = 28 then ReadKeyNr := CtrlReturnKey
  396.                           else ReadKeyNr := 10 ; { ^J }
  397.           13 : if AH = 28 then ReadKeyNr := ReturnKey
  398.                           else ReadKeyNr := 13 ; { ^M }
  399.           27 : if AH = 1  then ReadKeyNr := EscapeKey
  400.                           else ReadKeyNr := 27 ; { ^[ }
  401.           else ReadKeyNr := AL ;
  402.           end ; { of case }
  403.      end ; { of with }
  404. end ;
  405.  
  406. {-----------------------------------------------------------------------------}
  407. { Puts a line of text on the last line of the screen.                         }
  408. { Writes directly into video memory.                                          }
  409. {-----------------------------------------------------------------------------}
  410.  
  411. procedure SetBottomLine (LineText:string) ;
  412.  
  413. var ScrEl : ScreenElement ;
  414.     Col : byte ;
  415.     NewBottomLine : array[1..ColsOnScreen] of ScreenElement ;
  416.  
  417. begin
  418. { fill rest of LineText with spaces until length = ColsOnScreen }
  419. for Col := (Length(LineText)+1) to ColsOnScreen do
  420.     LineText[Col] := ' ' ;
  421. LineText[0] := char(ColsOnScreen) ;
  422. { set attribute }
  423. ScrEl.Attribute := ScreenColorArray[Config.Setup.ScreenColors].StatusAttr ;
  424. { fill bottom line of screen }
  425. for Col := 1 to ColsOnScreen do
  426.     begin
  427.     ScrEl.Contents := LineText[Col] ;
  428.     NewBottomLine[Col] := ScrEl ;
  429.     end ;
  430. MoveToScreen (NewBottomLine[1],DisplayPtr^[LinesOnScreen,1],2*ColsOnScreen) ;
  431. end ;
  432.  
  433. {-----------------------------------------------------------------------------}
  434. { Produces a message on the last line of the screen and sets MessageRead      }
  435. {-----------------------------------------------------------------------------}
  436.  
  437. procedure Message (Contents:string) ;
  438.  
  439. begin
  440. SetBottomLine (Contents) ;
  441. MessageRead := (Length(Contents) = 0) ;
  442. end ;
  443.  
  444. {-----------------------------------------------------------------------------}
  445. { Produces an error beep (if allowed by Setup), writes an error message       }
  446. { corresponding to the error number, on the last screen line and waits        }
  447. { until the Escape key is pressed.                                            }
  448. { If any macros are running, they are canceled.                               }
  449. {-----------------------------------------------------------------------------}
  450.  
  451. procedure ErrorMessage (ErrorNr:byte) ;
  452.  
  453. var ErrorText : string[ColsOnScreen] ;
  454.  
  455. begin
  456. if Config.Setup.SoundBell
  457.    then begin
  458.         Sound(880) ;
  459.         Delay(100) ;
  460.         NoSound ;
  461.         end ;
  462. case ErrorNr of
  463.        1 : ErrorText := 'Not enough memory' ;
  464.        4 : ErrorText := 'Block too large for paste buffer' ;
  465.        5 : ErrorText := 'No block defined' ;
  466.        6 : ErrorText := 'Maximum macro length reached. End of define mode' ;
  467.        7 : ErrorText := 'File too large. Only partially read' ;
  468.        8 : ErrorText := 'File not found' ;
  469.        9 : ErrorText := 'Cyclic macro definition. Key ignored' ;
  470.       10 : ErrorText := 'Too many macros nested. Execution canceled' ;
  471.       11 : ErrorText := 'Not in word wrap mode' ;
  472.       12 : ErrorText := 'Position stack full' ;
  473.       13 : ErrorText := 'Position stack empty' ;
  474.       14 : case DosError of
  475.                 2  : ErrorText := 'Can not find COMMAND.COM ' ;
  476.                 8  : ErrorText := 'Not enough memory to execute DOS command' ;
  477.                 else ErrorText := 'DOS error '+WordToString(DosError,2) ;
  478.                 end ; { of case }
  479.       15 : ErrorText := 'String not found' ;
  480.       16 : ErrorText := 'Illegal file name' ;
  481.       17 : case DiskError of
  482.                 2   : ErrorText := 'File not found' ;
  483.                 3   : ErrorText := 'Path not found' ;
  484.                 5   : ErrorText := 'File acces denied' ;
  485.                 101 : ErrorText := 'Disk write error' ;
  486.                 150 : ErrorText := 'Disk is write-protected' ;
  487.                 152 : ErrorText := 'Drive not ready' ;
  488.                 159 : ErrorText := 'Printer out of paper' ;
  489.                 160 : ErrorText := 'Device write fault' ;
  490.                 else  ErrorText := 'I/O error ' + WordToString (DiskError,0) ;
  491.                 end ; { of case }
  492.       end ; { of case }
  493. SetBottomLine (ErrorText+' (press Esc)') ;
  494. repeat until ReadKeyNr = EscapeKey ;
  495. if MacroStackpointer <> Inactive
  496.    then begin
  497.         MacroStackpointer := Inactive ;
  498.         Message ('Macro execution canceled') ;
  499.         end
  500.    else Message ('') ;
  501. end ;
  502.  
  503. {-----------------------------------------------------------------------------}
  504. { Like the DOS batch command, Pause displays the message 'Press any key to    }
  505. { continue' and then waits until a key is pressed.                            }
  506. {-----------------------------------------------------------------------------}
  507.  
  508. procedure Pause ;
  509.  
  510. var DummyKey : word ;
  511.  
  512. begin
  513. SetBottomLine ('Press any key to continue') ;
  514. DummyKey := ReadKeyNr ;
  515. EscPressed := (DummyKey = EscapeKey) ;
  516. SetBottomLine ('') ;
  517. end ;
  518.  
  519. {-----------------------------------------------------------------------------}
  520. { Reads the result of the last I/O operation into the DiskError variable      }
  521. { and produces an error message if an error has occurred.                     }
  522. {-----------------------------------------------------------------------------}
  523.  
  524. procedure CheckDiskError ;
  525.  
  526. begin
  527. DiskError := IOResult ;
  528. if DiskError <> 0 then ErrorMessage (17) ;
  529. end ;
  530.  
  531. {-----------------------------------------------------------------------------}
  532. { Draws a frame on the text screen between (X1,Y1) and (X2,Y2)                }
  533. {-----------------------------------------------------------------------------}
  534.  
  535. procedure PutFrame (X1,Y1,X2,Y2 : byte ; Border : string) ;
  536.  
  537. var i : byte ;
  538.  
  539. begin
  540. CursorTo (X1,Y1) ; Write (Border[1]) ; { upper left corner }
  541. for i := Succ(X1) to Pred(X2) do Write (Border[2]) ; { upper side }
  542. Write (Border[3]) ; { upper right corner }
  543. for i := Succ(Y1) to Pred(Y2) do
  544.     begin
  545.     CursorTo (X1,i) ; Write (Border[8]) ; { left side }
  546.     CursorTo (X2,i) ; Write (Border[4]) ; { right side }
  547.     end ;
  548. CursorTo (X1,Y2) ; Write (Border[7]) ; { lower right corner }
  549. for i := Succ(X1) to Pred(X2) do Write (Border[6]) ; { lower side }
  550. Write (Border[5]) ; { lower left corner }
  551. end ;
  552.  
  553. {-----------------------------------------------------------------------------}
  554. { Clears a rectangular screen area between (X1,Y1) and (X2,Y2).               }
  555. {-----------------------------------------------------------------------------}
  556.  
  557. procedure ClearArea (X1,Y1,X2,Y2 : byte) ;
  558.  
  559. var OldWindMax,OldWindMin : word ;
  560.  
  561. begin
  562. OldWindMax := WindMax ;
  563. OldWindMin := WindMin ;
  564. Window (X1,Y1,X2,Y2) ;
  565. ClrScr ;
  566. Window (Lo(OldWindMin)+1,Hi(OldWindMin)+1,
  567.         Lo(OldWindMax)+1,Hi(OldWindMax)+1) ;
  568. end ;
  569.  
  570. {-----------------------------------------------------------------------------}
  571. { Clears the workspace indicated by <Wsnr>, resetting all variables.          }
  572. {-----------------------------------------------------------------------------}
  573.  
  574. procedure ClearWorkspace (Wsnr:byte) ;
  575.  
  576. begin
  577. with Workspace[Wsnr] do
  578.      begin
  579.      Name := '' ;
  580.      ChangesMade := False ;
  581.      GetTime (LastTimeSaved[1],LastTimeSaved[2],
  582.               LastTimeSaved[3],LastTimeSaved[4]) ;
  583.      CurPos.Index := 1 ;
  584.      CurPos.Linenr := 1 ;
  585.      CurPos.Colnr := 1 ;
  586.      Mark := Inactive ;
  587.      FirstVisiblePos := CurPos ;
  588.      FirstScreenCol := 1 ;
  589.      VirtualColnr := 1 ;
  590.      Buffer^[1] := EF ;
  591.      Buffersize := 1 ;
  592.      PosStackPointer := Inactive ;
  593.      end ;
  594. end ;
  595.  
  596. {-----------------------------------------------------------------------------}
  597. { Clears the keys in the keyboard buffer.                                     }
  598. {-----------------------------------------------------------------------------}
  599.  
  600. procedure ClearKeyBuffer ;
  601.  
  602. var DummyKey : char ;
  603.  
  604. begin
  605. while KeyPressed do DummyKey := ReadKey ;
  606. end ;
  607.  
  608. {-----------------------------------------------------------------------------}
  609.  
  610. end.
  611.